home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-12-15 | 6.4 KB | 218 lines | [TEXT/MPS ] |
- ////////////////////////////////////////////////////////////////////
- //
- // PlaySnd.c - the Play Sound OSAX
- //
- // Copyright ®1993 Apple Computer Inc.
- // All rights reserved
- //
- // Written by: Donald Olson
- //
- ////////////////////////////////////////////////////////////////////
-
- #include <Resources.h>
- #include <Sound.h>
- #include <AppleEvents.h>
-
-
- #define kAsync true // asynchronous play
- #define kQuietNow true // quiet channel now
-
- #define kSndType 'snd ' // resource type we're looking for
- #define typeIntlText 'itxt' // defined in AERegistry.r
- #define typeStyledText 'STXT' // defined in AERegistry.r
-
- ////////////////////////////////////////////////////////////////////
- //
- // PlaySndEntry ()
- //
- // The direct parameter is either a name or an id of the 'snd '
- // resource to play.
- //
- ////////////////////////////////////////////////////////////////////
-
- pascal OSErr PlaySndEntry( AppleEvent *theAEEvent,
- AppleEvent *theReply,
- long *theRefCon)
-
- {
- #pragma unused(theReply, theRefCon)
-
- /* Function Prototypes */
- OSErr PlaySound(Handle theSoundHdl);
-
- /* variables */
- OSErr theErr = noErr;
- DescType typeCode;
- Size sizeOfParam,
- actualSize;
- Handle theSndHandle = nil; // Just clear our sound handle
- SndChannelPtr theSndChan = NULL; // NULL pointer to a sound channel
- short ourRezID = 0;
- Str255 ourRezName;
- FSSpec ourSoundFile;
- short ourFileRef, curResFile;
-
- /*
- Get the data type from direct object by using AESizeOfParam.
- We use this call instead of AEGetParamDesc or AEGetParamPtr
- since we are looking for one of several types. This way we
- can determine the type and move its data directly into a variable
- instead of an AEDesc. Makes our life easier since we don't
- have to worry about disposing the AEDesc later.
- */
-
- theErr = AESizeOfParam( theAEEvent,
- keyDirectObject,
- &typeCode,
- &sizeOfParam);
-
- if(theErr != noErr){
- /*
- If we fail here just return the error. We don't need to
- do any clean up since we've allocated nothing on the heap
- yet. The Apple Event Manager automatically adds the error
- number to the reply as keyErrorNumber for non zero handler
- returns.
- */
-
- return theErr;
- }
- else{
- if((typeCode == typeChar) || (typeCode == typeStyledText) ||
- (typeCode == typeIntlText)) {
- /*
- If one of these types match, we've been passed a name of
- a resource. Use AEGetParamPtr to move it into our string
- and transform it into a Pascal type string that we can
- pass to GetNamedResource. If we get an error in AEGetParamPtr,
- Just let it fall through to the bottom of this handler.
- */
-
- theErr = AEGetParamPtr(theAEEvent, keyDirectObject, typeChar,
- &typeCode, (Ptr)&ourRezName,
- sizeof(ourRezName), &actualSize);
-
- if(theErr == noErr) {
- /* 'C' string has a null as last char */
- ourRezName[actualSize] = '\0';
- /* Convert to Pascal string */
- c2pstr((char*) ourRezName);
- /* Now grab the 'snd ' resource by name*/
- theSndHandle = GetNamedResource(kSndType,
- (ConstStr255Param)ourRezName);
- /* Check the error */
- theErr = ResError();
- if(theErr == noErr)
- theErr = PlaySound(theSndHandle); // Call our sound code
- }
- }
- else {
- if(typeCode == typeLongInteger) {
-
- /* If we get a typeLongInteger, the user wants us to play
- a sound by its resource id.
-
- AppleScript will send us a long here and the Resource
- Manager wants us to pass in a short so let's have the
- Apple Event Manager coerce it to a short for us.
- */
-
- theErr = AEGetParamPtr(theAEEvent, keyDirectObject,
- typeShortInteger, &typeCode,
- (Ptr)&ourRezID, sizeof(ourRezID),
- &actualSize);
-
- if(theErr == noErr) {
- /* Now grab the 'snd ' resource by id */
- theSndHandle = GetResource (kSndType, ourRezID);
- /* Check the error */
- theErr = ResError();
- if(theErr == noErr)
- theErr = PlaySound(theSndHandle); // Call our sound code
- }
- }
- else {
- if(typeCode == typeAlias) {
-
- /* It we receive a typeAlias, the user is asking us
- to play a sound file. We want to use a FSSpec to
- open the Resource File so once again we ask the
- Apple Event Manager to coerce data to the type we
- need.
- */
-
- theErr = AEGetParamPtr(theAEEvent, keyDirectObject,
- typeFSS, &typeCode,
- (Ptr)&ourSoundFile, sizeof(ourSoundFile),
- &actualSize);
- if(theErr != noErr)
- return theErr;
- /* Save off our current resource file */
- curResFile = CurResFile();
-
- /* Open our resource file for reading */
- ourFileRef = FSpOpenResFile(&ourSoundFile, fsRdPerm);
-
- /* Check the error */
- theErr = ResError();
- if(theErr != noErr)
- return theErr;
-
- /* Make our files resource fork top in the chain */
- UseResFile(ourFileRef);
-
- /*
- Since we don't know for sure the resource id of the
- targeted files 'snd ' resource, let's just get the first
- (and supposedly only) one.
- */
-
- theSndHandle = Get1IndResource(kSndType, 1);
-
- /* Check the error */
- theErr = ResError();
- if(theErr == noErr)
- theErr = PlaySound(theSndHandle);
-
- // Restore resource chain and close our file
- UseResFile(curResFile);
- CloseResFile(ourFileRef);
- }
- else // Wasn't a string, alias or number so bail
- return errAEEventNotHandled;
- }
- }
- }
-
- // Dispose 'snd ' handle if necessary
- if(theSndHandle != nil) ReleaseResource(theSndHandle);
-
- return theErr;
- }
-
- ////////////////////////////////////////////////////////////////////
- //
- // PlaySound(Handle theSoundHdl)
- //
- // This is the code to play a 'snd '.
- //
- ////////////////////////////////////////////////////////////////////
-
- OSErr PlaySound(Handle theSoundHdl)
- {
- /* Our variables */
- OSErr theErr = noErr;
- SndChannelPtr theSndChan = NULL; // NULL pointer to a sound channel
-
- /* Open a channel so we can do synchronous play. */
- theErr = SndNewChannel (&theSndChan, sampledSynth, initMono, NULL);
-
- if (theErr == noErr) /* Play that sound */
- theErr = SndPlay (theSndChan, theSoundHdl, !kAsync);
-
- /* dispose of the channel, if soundchannel was allocated */
- if (theSndChan != NULL)
- SndDisposeChannel(theSndChan, !kQuietNow);
-
- return theErr;
- }